import { Component, createRef } from "inferno";
import TabView from "./TabView";
import ListView from "./ListView";
import Header from "./ui/Header";
import SoftKey from "./ui/SoftKey";
import TextListItem from "./ui/TextListItem";
import About from "./About";
import DMsView from "./DMsView";
import colors from "KaiUI/src/theme/colors.scss";
import requestFunc from "./requestFunc";
import CallScreen from "./CallScreen";
import personIcon from "./person_icon.png";
import { pushSubscribe } from "./utils";
import * as localforage from "localforage";
import * as matrixcs from "matrix-js-sdk";

function makeCallScreen(call, softKeyRef, callEndCb, incoming) {
  const client = window.mClient;
  const roomCall = client.getRoom(call.roomId);
  const theOther = client.getUser(roomCall.guessDMUserId());
  const avatarUrl = theOther.avatarUrl;
  const displayName = theOther.displayName || theOther.userId;
  let avatarSrc;
  if (avatarUrl) {
    avatarSrc = matrixcs.getHttpUriForMxc(
      client.getHomeserverUrl(),
      avatarUrl,
      180,
      180,
      "scale"
    );
  } else {
    avatarSrc = personIcon;
  }
  return (
    <CallScreen
      name={displayName}
      avatarSrc={avatarSrc}
      call={call}
      softKeyRef={softKeyRef}
      incoming={incoming}
      callEndCb={callEndCb}
    />
  );
}

class Matrix extends Component {
  handleTabIndexChange = (tabIndex) => {
    this.setState({ currentTab: tabIndex });
  };

  placeCall = (roomId) => {
    let call = matrixcs.createNewMatrixCall(window.mClient, roomId);
    let audio = new Audio();
    audio.mozAudioChannelType = "telephony";
    call.setRemoteAudioElement(audio);
    call.placeVoiceCall();
    this.callScreen = makeCallScreen(
      call,
      this.softKeyRef,
      this.callEnd,
      false
    );
    this.setState({ isCall: true });
  };

  centerCb = () => {
    this.headerRef.current.setState({
      blink: !this.headerRef.current.state.blink,
    });
  };

  onTabChange = (currentTab) => {
    this.currentTab = this.tabLabels[currentTab];
  };

  openRoom = (roomId) => {
    console.log("OPENING", roomId);
  };
  callEnd = (err) => {
    if (err) {
      alert("Call ended with Error!");
    }
    this.callScreen = null;
    this.setState({ isCall: false });
  };

  constructor(props) {
    super(props);
    const { login } = props;
    window.mClient = matrixcs.createClient({
      request: requestFunc,
      userId: login.user_id,
      accessToken: login.access_token,
      deviceId: login.device_id,
      baseUrl: login.well_known["m.homeserver"].base_url,
      identityServer:
        login.well_known["m.identity_server"] &&
        login.well_known["m.identity_server"].base_url,
    });
    this.tabLabels = ["People", "Rooms", "Invites", "Settings", "About"];
    this.headerRef = createRef();
    this.header = (
      <Header
        text={"Welcome!"}
        backgroundColor={colors.headerPurple}
        ref={this.headerRef}
      />
    );
    this.softKeyRef = createRef();
    this.softKey = (
      <SoftKey
        centerText={"blink"}
        centerCb={this.centerCb}
        ref={this.softKeyRef}
      />
    );
    this.callScreen = null;
    pushSubscribe();
    this.state = { isCall: false, syncDone: false };
  }

  componentWillMount() {
    const client = window.mClient;
    client.on("RoomMember.membership", (event, member) => {
      const myId = window.mClient.getUserId();
      if (member.membership === "invite" && member.userId === myId) {
        window.mClient
          .joinRoom(member.roomId)
          .then(() => alert(`Auto joined ${member.name}`))
          .catch(() => {});
      }
    });
    client.once("sync", (state, prevState, res) => {
      this.setState({ syncDone: true });
    });
    client.on("Call.incoming", (call) => {
      console.log("INCOMING", call);
      call.once("state", (state) => {
        if (this.state.isCall || call.type !== "voice") {
          call.reject();
        } else {
          this.callScreen = makeCallScreen(
            call,
            this.softKeyRef,
            this.callEnd,
            true
          );
          this.setState({ isCall: true });
        }
      });
    });
    client.on("Session.logged_out", () => {
      console.log("Logging out"); // FIXME
      localforage.removeItem("login").then(() => {
        window.location = window.location; // eslint-disable-line no-self-assign
      });
    });
    client.startClient({ initialSyncLimit: 3, lazyLoadMembers: true });
  }

  render() {
    if (!this.state.syncDone) {
      return (
        <div>
          {this.header}
          <div>Please wait I am syncing your account</div>
          <footer>{this.softKey}</footer>
        </div>
      );
    }
    if (this.state.isCall) {
      console.log("CALL SCREEN IS ", this.callScreen);
      return (
        <div>
          {this.header}
          {this.callScreen}
          <footer>{this.softKey}</footer>
        </div>
      );
    }
    return (
      <div>
        {this.header}
        <TabView
          tabLabels={this.tabLabels}
          onTabChange={this.onTabChange}
          $HasNonKeyedChildren
        >
          <DMsView
            updateFocusRoomCb={this.updateFocusDM}
            softKeyRef={this.softKeyRef}
            openRoom={this.openRoom}
            placeCall={this.placeCall}
          />
          <ListView cursor={0}>
            <TextListItem primary={"a room"} />
            <TextListItem primary={"another room"} />
          </ListView>
          <ListView cursor={0}>
            <TextListItem primary={"an invite"} />
          </ListView>
          <ListView cursor={0}>
            <TextListItem primary={"some options"} />
          </ListView>
          <About softKeyRef={this.softKeyRef} />
        </TabView>
        <footer $HasVNodeChildren>{this.softKey}</footer>
      </div>
    );
  }
}

export default Matrix;
